home *** CD-ROM | disk | FTP | other *** search
- #include <fcntl.h>
- #include <stat.h>
- #include <types.h>
- #include <errno.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- /**
- ** (sjk)++ These routines simulate a eunchs pipe() call using temporary
- ** files. A linked list of type *_pipe is kept as to allow as
- ** many open pipes as there are valid file descriptors. The only
- ** problem is that the pipe is initiallialy opened for writing,
- ** and all output must be done to the pipe, then call pipeclose(fd);
- ** and it sets up the pipe for reading. After all input is done,
- ** call pipeclose(fd) again and this will close the pipe and delete
- ** the temporary file that the pipe created.
- **
- **/
-
- struct _pipe { char p_name[40];
- char flag; /* "r"-->read, "w"-->write */
- int file_des;
- struct _pipe *next;
- };
- static struct _pipe *__pipes = NULL;
-
- /*---------------------------------------------------------------------------*/
- /* Make a pipe, open the tempory file, set it up for writing, add the pipe */
- /* descriptor to our linked list of pipes, and return. */
- /*---------------------------------------------------------------------------*/
- int pipe(fildes)
- int fildes[2];
- { int fd,ifd;
- char name[40];
- struct _pipe *p;
-
- tmpnam(name); /* Make a temporary file name. /*
-
- /*----------------------------------------------*/
- /* Open the pipe for reading and writing. */
- /*----------------------------------------------*/
- fd = open(name,O_CREAT | O_TRUNC | O_RDWR | O_PIPE, 0644);
-
- if (fd < 0)
- fprintf(stderr,"fd returns : %d! PIPE failed.\n",fd);
- else
- { /*------------------------------------------*/
- /* Get a pipe description block and */
- /* put in the (1)file name, */
- /* (2)file descriptor, */
- /* (3)file mode = "w". */
- /*------------------------------------------*/
- /*-------------------------------------------------------------------*/
- p = (struct _pipe *)malloc(sizeof (struct _pipe));
- strcpy(p->p_name,name); /* fill in name. */
- p->flag = 'w'; /* initially for write. */
- p->file_des = fd; /* fill in the pipe descriptor. */
- /*-------------------------------------------------------------------*/
- p->next = __pipes; /* Link to our list of open pipes. */
- __pipes = p;
- /*-------------------------------------------------------------------*/
- fildes[0] = fildes[1] = fd; /* we fill in fildes[]. */
- }
- return(fd); /* Return the file descriptor. */
- }
-
- /*---------------------------------------------------------------------*/
- /* close a pipe, if the pipe was open for writing, set it to a read */
- /* read pipe, and lseek to the begining of the pipe. if it was open */
- /* for reading then close the pipe, delete the temporary file, and */
- /* remove the pipe descriptor from the __pipes linked list. */
- /*---------------------------------------------------------------------*/
- int
- pipeclose(fd)
- int fd;
- { struct _pipe *p,*q = NULL;
- int ifd;
- for (p=__pipes; p; p=p->next)
- { if (fd == p->file_des)
- if (p->flag == 'r')
- { int res;
- ifd = __OPEN_INDEX(fd);
- __open_stat[ifd].pipe = 0; /* So close wont recurse */
- res = close(fd);
- unlink(p->p_name); /* Delete it. */
- del_list(p); /* delete from the list. */
- return(res);
- }
- else
- if (p->flag =='w')
- { p->flag = 'r'; /* now make it read. */
- lseek(p->file_des,0,SEEK_SET); /* read from the start. */
- return(0);
- }
- }
- fprintf(stderr,"attempt to close nonexistant pipe.\n");
- return(-1);
- }
-
- /*---------------------------------------------------------------------*/
- /* delete a pipe descriptor from our list of pipes rooted ar __pipes. */
- /*---------------------------------------------------------------------*/
- del_list(p)
- struct _pipe *p;
- { struct _pipe *q,*r;
-
- if (p == __pipes) /* Is it the first element? */
- { __pipes = p->next;
- free(p);
- return(0);
- }
- else
- { r = p->next; q = p; /* No it is interior. */
- for (; r; r = r->next)
- { if (r == p)
- { q->next = r->next; /* pass over it. */
- free(r); /* free its space. */
- return(0); /* go home. */
- }
- q = r; /* update trailing pointer. */
- }
- }
- fprintf(stderr,"Attempt to delete a nonexisting pipe form list (__pipes).");
- }
-
-